package com.gpframework.module.purchase.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gpframework.common.enums.YesNoEnum;
import com.gpframework.common.utils.DateUtils;
import com.gpframework.common.utils.StringUtils;
import com.gpframework.module.module.domain.GpDeliveryNote;
import com.gpframework.module.module.domain.GpIncomingInspectWeight;
import com.gpframework.module.module.domain.GpIncomingInspectWidth;
import com.gpframework.module.module.domain.GpIncomingInspectYardVerify;
import com.gpframework.module.module.domain.vo.GpIncomingInspectWeightVo;
import com.gpframework.module.module.domain.vo.GpIncomingInspectWidthVo;
import com.gpframework.module.module.domain.vo.GpIncomingInspectYardVerifyVo;
import com.gpframework.module.purchase.domain.*;
import com.gpframework.module.purchase.domain.req.GpPurchaseIncomingInspectUpdate;
import com.gpframework.module.purchase.domain.req.GpPurchaseReceiptUpdate;
import com.gpframework.module.purchase.domain.vo.GpPurchaseIncomingInspectWeightVo;
import com.gpframework.module.purchase.domain.vo.GpPurchaseIncomingInspectWidthVo;
import com.gpframework.module.purchase.domain.vo.GpPurchaseIncomingInspectYardVerifyVo;
import com.gpframework.module.purchase.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gpframework.module.purchase.mapper.GpPurchaseIncomingInspectMapper;
import com.gpframework.module.purchase.domain.vo.GpPurchaseIncomingInspectVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * @ClassName GpPurchaseIncomingInspect
 * @Author gpframework
 * @Date 2024-01-09
 * @Version 1.0.0
 * @Description 采购来料检验单Service业务层处理
 */
@Service
public class GpPurchaseIncomingInspectServiceImpl extends ServiceImpl<GpPurchaseIncomingInspectMapper, GpPurchaseIncomingInspect> implements IGpPurchaseIncomingInspectService {

    @Autowired
    private IGpPurchaseReceiptService iGpPurchaseReceiptService;
    @Autowired
    private IGpPurchaseIncomingInspectYardVerifyService iGpPurchaseIncomingInspectYardVerifyService;
    @Autowired
    private IGpPurchaseIncomingInspectWidthService iGpPurchaseIncomingInspectWidthService;
    @Autowired
    private IGpPurchaseIncomingInspectWeightService iGpPurchaseIncomingInspectWeightService;

    /**
     * @Description 查询列表返回VO 用于返回给前端的列表接口
     * @Author gpframework
     * @Date 2024-01-09
     * @Param [lqw]
     * @Return List<GpPurchaseIncomingInspectVo>
     */
    @Override
    public List<GpPurchaseIncomingInspectVo> listVo(QueryWrapper<GpPurchaseIncomingInspect> lqw) {
        List<GpPurchaseIncomingInspectVo> listVo = this.baseMapper.listVo(lqw);
        for (GpPurchaseIncomingInspectVo gpPurchaseIncomingInspectVo : listVo) {
            getSubList(gpPurchaseIncomingInspectVo);
        }
        return listVo;
    }

    private void getSubList(GpPurchaseIncomingInspectVo gpPurchaseIncomingInspectVo) {
        gpPurchaseIncomingInspectVo.setYardVerifyList(iGpPurchaseIncomingInspectYardVerifyService.listVo(new QueryWrapper<GpPurchaseIncomingInspectYardVerify>().eq("incoming_inspect_id", gpPurchaseIncomingInspectVo.getId()).eq("del_status", YesNoEnum.NO.getKey()).orderByAsc("create_time")));
        gpPurchaseIncomingInspectVo.setWidthList(iGpPurchaseIncomingInspectWidthService.listVo(new QueryWrapper<GpPurchaseIncomingInspectWidth>().eq("incoming_inspect_id", gpPurchaseIncomingInspectVo.getId()).eq("del_status", YesNoEnum.NO.getKey()).orderByAsc("create_time")));
        gpPurchaseIncomingInspectVo.setWeightList(iGpPurchaseIncomingInspectWeightService.listVo(new QueryWrapper<GpPurchaseIncomingInspectWeight>().eq("incoming_inspect_id", gpPurchaseIncomingInspectVo.getId()).eq("del_status", YesNoEnum.NO.getKey()).orderByAsc("create_time")));
        // 实际验码导出
        List<GpPurchaseIncomingInspectYardVerifyVo> yardVerifyList = gpPurchaseIncomingInspectVo.getYardVerifyList();
        if (!CollectionUtils.isEmpty(yardVerifyList)) {
            GpPurchaseIncomingInspectYardVerifyVo gpIncomingInspectYardVerify;
            for (int i = 0; i < yardVerifyList.size(); i++) {
                gpIncomingInspectYardVerify = yardVerifyList.get(i);
                switch (i) {
                    case 0:
                        gpPurchaseIncomingInspectVo.setYardOne(gpIncomingInspectYardVerify.getYard());
                        break;
                    case 1:
                        gpPurchaseIncomingInspectVo.setYardTwo(gpIncomingInspectYardVerify.getYard());
                        break;
                    case 2:
                        gpPurchaseIncomingInspectVo.setYardThree(gpIncomingInspectYardVerify.getYard());
                        break;
                    case 3:
                        gpPurchaseIncomingInspectVo.setYardFour(gpIncomingInspectYardVerify.getYard());
                        break;
                    case 4:
                        gpPurchaseIncomingInspectVo.setYardFive(gpIncomingInspectYardVerify.getYard());
                        break;
                    default:
                        break;
                }
            }
        }
        // 幅宽导出
        List<GpPurchaseIncomingInspectWidthVo> widthList = gpPurchaseIncomingInspectVo.getWidthList();
        if (!CollectionUtils.isEmpty(widthList)) {
            GpPurchaseIncomingInspectWidthVo gpIncomingInspectWidth;
            for (int i = 0; i < widthList.size(); i++) {
                gpIncomingInspectWidth = widthList.get(i);
                switch (i) {
                    case 0:
                        gpPurchaseIncomingInspectVo.setStartWidthOne(gpIncomingInspectWidth.getStartWidth());
                        gpPurchaseIncomingInspectVo.setMiddleWidthOne(gpIncomingInspectWidth.getMiddleWidth());
                        gpPurchaseIncomingInspectVo.setEndWidthOne(gpIncomingInspectWidth.getEndWidth());
                        break;
                    case 1:
                        gpPurchaseIncomingInspectVo.setStartWidthTwo(gpIncomingInspectWidth.getStartWidth());
                        gpPurchaseIncomingInspectVo.setMiddleWidthTwo(gpIncomingInspectWidth.getMiddleWidth());
                        gpPurchaseIncomingInspectVo.setEndWidthTwo(gpIncomingInspectWidth.getEndWidth());
                        break;
                    default:
                        break;
                }
            }
        }
        // 重量导出
        List<GpPurchaseIncomingInspectWeightVo> weightList = gpPurchaseIncomingInspectVo.getWeightList();
        if (!CollectionUtils.isEmpty(weightList)) {
            GpPurchaseIncomingInspectWeightVo gpIncomingInspectWeight;
            for (int i = 0; i < weightList.size(); i++) {
                gpIncomingInspectWeight = weightList.get(i);
                switch (i) {
                    case 0:
                        gpPurchaseIncomingInspectVo.setWeightOne(gpIncomingInspectWeight.getWeight());
                        break;
                    case 1:
                        gpPurchaseIncomingInspectVo.setWeightTwo(gpIncomingInspectWeight.getWeight());
                        break;
                    case 2:
                        gpPurchaseIncomingInspectVo.setWeightThree(gpIncomingInspectWeight.getWeight());
                        break;
                    case 3:
                        gpPurchaseIncomingInspectVo.setWeightFour(gpIncomingInspectWeight.getWeight());
                        break;
                    case 4:
                        gpPurchaseIncomingInspectVo.setWeightFive(gpIncomingInspectWeight.getWeight());
                        break;
                    default:
                        break;
                }
            }
        }
    }

    /**
     * @Description 通过查询详情VO 用于返回给前端的列详情接口
     * @Author gpframework
     * @Date 2024-01-09
     * @Param [id]
     * @Return GpPurchaseIncomingInspectVo
     */
    @Override
    public GpPurchaseIncomingInspectVo getVoById(Long id) {
        GpPurchaseIncomingInspectVo gpPurchaseIncomingInspectVo = this.baseMapper.getVo(id);
        getSubList(gpPurchaseIncomingInspectVo);
        return gpPurchaseIncomingInspectVo;
    }

    @Override
    public boolean addIncomingInspect(GpPurchaseReceiptUpdate gpPurchaseReceiptUpdate) {
        List<Long> ids = gpPurchaseReceiptUpdate.getIds();
        GpPurchaseReceipt gpPurchaseReceipt;
        List<GpPurchaseIncomingInspect> list = new ArrayList<>();
        for (Long id : ids) {
            gpPurchaseReceipt = iGpPurchaseReceiptService.getById(id);
            if (gpPurchaseReceipt == null) {
                continue;
            }
            GpPurchaseIncomingInspect gpPurchaseIncomingInspect = Convert.convert(new TypeReference<GpPurchaseIncomingInspect>() {}, gpPurchaseReceipt);
            if (StringUtils.isNotBlank(gpPurchaseReceiptUpdate.getCreateBy())) {
                gpPurchaseIncomingInspect.setCreateBy(gpPurchaseReceiptUpdate.getCreateBy());
            }
            gpPurchaseIncomingInspect.setSn(this.getSn());
            gpPurchaseIncomingInspect.setIncomingTime(new Date());
            gpPurchaseIncomingInspect.setSupplierName(gpPurchaseReceipt.getSupplier());
            gpPurchaseIncomingInspect.setColour(gpPurchaseReceipt.getProductColor());
            gpPurchaseIncomingInspect.setTotalQuantity(Integer.parseInt(gpPurchaseReceipt.getTotalSize()));
            gpPurchaseIncomingInspect.setCodingSpecifications(gpPurchaseReceipt.getNorms());
            list.add(gpPurchaseIncomingInspect);
        }
        boolean saveBatch = this.saveBatch(list);
        if (saveBatch) {
            this.createSubList(list);
        }
        return saveBatch;
    }

    private void createSubList(List<GpPurchaseIncomingInspect> list) {
        for (GpPurchaseIncomingInspect gpPurchaseIncomingInspect : list) {
            GpPurchaseIncomingInspectYardVerify gpPurchaseIncomingInspectYardVerify;
            GpPurchaseIncomingInspectWidth gpPurchaseIncomingInspectWidth;
            GpPurchaseIncomingInspectWeight gpPurchaseIncomingInspectWeight;
            for (int i = 0; i < 5; i++) {
                // 初始化验码
                gpPurchaseIncomingInspectYardVerify = new GpPurchaseIncomingInspectYardVerify();
                gpPurchaseIncomingInspectYardVerify.setIncomingInspectId(gpPurchaseIncomingInspect.getId());
                iGpPurchaseIncomingInspectYardVerifyService.save(gpPurchaseIncomingInspectYardVerify);
                // 初始化重量
                gpPurchaseIncomingInspectWeight = new GpPurchaseIncomingInspectWeight();
                gpPurchaseIncomingInspectWeight.setIncomingInspectId(gpPurchaseIncomingInspect.getId());
                iGpPurchaseIncomingInspectWeightService.save(gpPurchaseIncomingInspectWeight);
            }
            for (int j = 0; j < 3; j++) {
                // 初始化幅宽
                gpPurchaseIncomingInspectWidth = new GpPurchaseIncomingInspectWidth();
                gpPurchaseIncomingInspectWidth.setIncomingInspectId(gpPurchaseIncomingInspect.getId());
                iGpPurchaseIncomingInspectWidthService.save(gpPurchaseIncomingInspectWidth);
            }
        }
    }

    private String getSn() {
        String sn = "";

        String yyMMdd = DateUtils.getDate("yyMMdd");
        sn += yyMMdd;

        GpPurchaseIncomingInspect gpPurchaseIncomingInspect = this.getOne(new LambdaQueryWrapper<GpPurchaseIncomingInspect>()
                .eq(GpPurchaseIncomingInspect::getDelStatus, YesNoEnum.NO.getKey())
                .isNotNull(GpPurchaseIncomingInspect::getSn)
                .gt(GpPurchaseIncomingInspect::getCreateTime, DateUtils.getDate("yyyy-MM-dd 00:00:00"))
                .orderByDesc(GpPurchaseIncomingInspect::getCreateTime)
                .last("limit 1"));
        if (gpPurchaseIncomingInspect == null) {
            sn += "-1";
        } else {
            String substring = gpPurchaseIncomingInspect.getSn().substring(gpPurchaseIncomingInspect.getSn().lastIndexOf("-") + 1);
            int index = Integer.parseInt(substring) + 1;
            sn += "-" + index;
        }
        return sn;
    }

    @Override
    public boolean edit(List<GpPurchaseIncomingInspectUpdate> updateList) {
        List<GpPurchaseIncomingInspect> list = Convert.convert(new TypeReference<List<GpPurchaseIncomingInspect>>() {}, updateList);
        boolean update = this.updateBatchById(list);
        if (update) {
            this.updateSubList(updateList);
        }
        return update;
    }

    @Override
    public boolean editOne(GpPurchaseIncomingInspectUpdate gpPurchaseIncomingInspectUpdate) {
        GpPurchaseIncomingInspect gpPurchaseIncomingInspect = Convert.convert(new TypeReference<GpPurchaseIncomingInspect>() {}, gpPurchaseIncomingInspectUpdate);
        boolean update = this.updateById(gpPurchaseIncomingInspect);
        if (update) {
            List<GpPurchaseIncomingInspectUpdate> updateList = new ArrayList<>();
            updateList.add(gpPurchaseIncomingInspectUpdate);
            this.updateSubList(updateList);
        }
        return update;
    }

    @Override
    public boolean copy(Long id, Integer copyNum) {
        GpPurchaseIncomingInspect gpPurchaseIncomingInspect = this.getById(id);
        if (gpPurchaseIncomingInspect == null) {
            return false;
        }

        List<GpPurchaseIncomingInspectYardVerify> yardVerifyList = iGpPurchaseIncomingInspectYardVerifyService.list(new LambdaQueryWrapper<GpPurchaseIncomingInspectYardVerify>().eq(GpPurchaseIncomingInspectYardVerify::getIncomingInspectId, gpPurchaseIncomingInspect.getId()).eq(GpPurchaseIncomingInspectYardVerify::getDelStatus, YesNoEnum.NO.getKey()));
        List<GpPurchaseIncomingInspectWidth> widthList = iGpPurchaseIncomingInspectWidthService.list(new LambdaQueryWrapper<GpPurchaseIncomingInspectWidth>().eq(GpPurchaseIncomingInspectWidth::getIncomingInspectId, gpPurchaseIncomingInspect.getId()).eq(GpPurchaseIncomingInspectWidth::getDelStatus, YesNoEnum.NO.getKey()));
        List<GpPurchaseIncomingInspectWeight> weightList = iGpPurchaseIncomingInspectWeightService.list(new LambdaQueryWrapper<GpPurchaseIncomingInspectWeight>().eq(GpPurchaseIncomingInspectWeight::getIncomingInspectId, gpPurchaseIncomingInspect.getId()).eq(GpPurchaseIncomingInspectWeight::getDelStatus, YesNoEnum.NO.getKey()));
        for (int i = 0; i < copyNum; i++) {
            gpPurchaseIncomingInspect.setId(null);
            this.save(gpPurchaseIncomingInspect);
            yardVerifyList.forEach(yardVerify -> yardVerify.setIncomingInspectId(gpPurchaseIncomingInspect.getId()));
            iGpPurchaseIncomingInspectYardVerifyService.saveBatch(yardVerifyList);
            widthList.forEach(yardVerify -> yardVerify.setIncomingInspectId(gpPurchaseIncomingInspect.getId()));
            iGpPurchaseIncomingInspectWidthService.saveBatch(widthList);
            weightList.forEach(yardVerify -> yardVerify.setIncomingInspectId(gpPurchaseIncomingInspect.getId()));
            iGpPurchaseIncomingInspectWeightService.saveBatch(weightList);
        }
        return false;
    }

    private void updateSubList(List<GpPurchaseIncomingInspectUpdate> updateList) {
        for (GpPurchaseIncomingInspectUpdate purchaseIncomingInspectUpdate : updateList) {
            // 更新验码
            List<GpPurchaseIncomingInspectYardVerify> yardVerifyList = purchaseIncomingInspectUpdate.getYardVerifyList();
            yardVerifyList.forEach(yardVerify -> yardVerify.setIncomingInspectId(purchaseIncomingInspectUpdate.getId()));
            iGpPurchaseIncomingInspectYardVerifyService.saveOrUpdateBatch(yardVerifyList);
            // 更新重量
            List<GpPurchaseIncomingInspectWeight> weightList = purchaseIncomingInspectUpdate.getWeightList();
            weightList.forEach(weight -> weight.setIncomingInspectId(purchaseIncomingInspectUpdate.getId()));
            iGpPurchaseIncomingInspectWeightService.saveOrUpdateBatch(weightList);
            // 更新幅宽
            List<GpPurchaseIncomingInspectWidth> widthList = purchaseIncomingInspectUpdate.getWidthList();
            widthList.forEach(width -> width.setIncomingInspectId(purchaseIncomingInspectUpdate.getId()));
            iGpPurchaseIncomingInspectWidthService.saveOrUpdateBatch(widthList);
        }
    }
}
